package com.sdk.server;

import com.sdk.business.SessionService;
import com.sdk.business.StakeService;
import com.sdk.business.impl.SessionServiceImpl;
import com.sdk.business.impl.StakeServiceImpl;
import com.sdk.cache.InMemoryCache;
import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

public class StakeHttpServer {

    private static final Logger logger = Logger.getLogger("StakeHttpServer");

    private final StakeService stakeService;

    private final SessionService sessionService;

    public StakeHttpServer(SessionService sessionService, StakeService stakeService) {
        this.stakeService = stakeService;
        this.sessionService = sessionService;
    }

    public void start() throws IOException {
        HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
        server.createContext("/", new HttpServerHandler(sessionService, stakeService));
        // Start the cleanup scheduler
        sessionService.startCleanupScheduler();
        // Shutdown the session service when the application is stopping
        Runtime.getRuntime().addShutdownHook(new Thread(sessionService::stopCleanupScheduler));
        server.setExecutor(buildThreadPoolExecutor());
        server.start();
        logger.info("Server started on port 8080");
    }

    private ThreadPoolExecutor buildThreadPoolExecutor() {
        int corePoolSize = 10;
        int maximumPoolSize = 20;
        long keepAliveTime = 60L;
        TimeUnit unit = TimeUnit.SECONDS;
        ArrayBlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(1024);

        return new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue
        );
    }

    public static void main(String[] args) throws IOException {
        InMemoryCache<String, String> sessionCache = new InMemoryCache<>();
        SessionService sessionService = new SessionServiceImpl(sessionCache);
        StakeService stakeService = new StakeServiceImpl();
        StakeHttpServer server = new StakeHttpServer(sessionService, stakeService);
        server.start();
    }
}
